#pragma once
#include <iostream>
#include "thread.hpp"
#include <vector>
#include <string>
#include <queue>
#include "lockGuard.hpp"

const int g_default_num=10;
//本质：生产消费模型
template<class T>
class ThreadPool
{
public:
    pthread_mutex_t *getlock()
    {
        return &_lock;
    }

    // void getlock()
    // {
    //     return pthrear_mutex_lock(&_lock);
    // }
    bool Empty()
    {
        return _task_queue.empty();
    }
    void waitcond()
    {
        pthread_cond_wait(&_cond,nullptr);
    }
    T gettask()
    {
        T t=_task_queue.front();
        _task_queue.pop();
        return t;
    }
public:
    ThreadPool ThreadPool_init(int num=g_default_num)
    {
        if(nullptr==thread_ptr)
        {
            lockGuard lockGuard(&_mutex);
            if(nullptr == thread_ptr)
                *thread_ptr = new ThreadPool<T>(num);
        }
        return *thread_ptr;
    }
    ~ThreadPool()
    {
        for(auto& iter:_threads)
        {
            iter->join();
            delete iter;
        }
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }
    void run()
    {
        for(auto& iter:_threads)
        {
            iter->start();
            // std::cout << iter->name() << " 启动成功" << std::endl;
            //logMessage(NORMAL, "%s %s", iter->name().c_str(), "启动成功"); //日志
        }
    }
    static void *routine(void *args)
    {
        ThreadData *td = (ThreadData *)args;//转化
        ThreadPool<T> *tp = (ThreadPool<T> *)td->_args;//转化

        T task();
        {
            //getlock();
            lockGuard lockguard(tp->getMutex());
            while(tp->Empty()) tp->waitcond;
            //pthread_cond_signal(&_cond,&_lock);
            task = tp->getTask();//任务
        }
         task(td->_name);
    }
    void pushTask(const T &task)//生产任务
    {
        lockGuard lockGuard(&_lock);//初始化所
        _task_queue.push(task);//队列插入任务
        pthread_cond_signal(&_cond);//唤醒线程
    }

private:
    ThreadPool(int num=g_default_num)
    :_num(num)//初始化
    {
        pthread_mutex_init(&_lock,nullptr);//互斥
        pthread_cond_init(&_cond,nullptr);//唤醒
        for(int i=0;i<_num;i++)
        {
            _threads.push_back(new thread(i,routine,this));//传入this指针
        }
    }
    ThreadPool(const ThreadPool<T>&)=delete;
    const ThreadPool<T> operator=(const ThreadPool<T>&)=delete;
private:
    std::vector<thread*> _threads;//线程
    int _num;//个数
    std::queue<T> _task_queue;//任务
    pthread_mutex_t _lock;//互斥锁
    pthread_cond_t _cond;//线程唤醒和等待
    static ThreadPool<T>* thread_ptr;//懒汉模式
    static pthread_mutex_t _mutex;
};

template<typename T>
ThreadPool<T>* ThreadPool<T>::thread_ptr=nullptr;
template<typename T>
pthread_mutex_t ThreadPool<T>::_mutex=PTHREAD_MUTEX_INITIALIZER;
